package com.cl.blog.service.impl;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cl.blog.common.Const;
import com.cl.blog.document.PigeonholeDto;
import com.cl.blog.entity.*;
import com.cl.blog.mapper.BCollectMapper;
import com.cl.blog.mapper.BUserLikeMapper;
import com.cl.blog.mq.DelayMessageSender;
import com.cl.blog.po.MonthPo;
import com.cl.blog.po.PigeonholePo;
import com.cl.blog.service.*;
import com.cl.blog.mapper.BContentMapper;
import com.cl.blog.util.JwtUtil;
import com.cl.blog.util.RedisUtil;
import com.cl.blog.vo.*;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.*;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author object
 * @description 针对表【b_content】的数据库操作Service实现
 * @createDate 2024-03-14 17:13:59
 */
@Service
@Slf4j
public class BContentServiceImpl extends ServiceImpl<BContentMapper, BContent>
		implements BContentService {

	@Resource
	BTypeService bTypeService;
	@Resource
	BTagService bTagService;
	@Resource
	BUserService bUserService;
	@Resource
	BContentMapper bContentMapper;
	@Autowired
	BCollectMapper bCollectMapper;
	@Autowired
	BUserLikeMapper bUserLikeMapper;
	@Autowired
	JwtUtil jwtUtil;
	@Autowired
	RedisUtil redisUtil;
	@Autowired
	BContentImageService bContentImageService;
//
//	@Autowired
//	private DelayMessageSender sender;

	@Override
	public Page<BContent> queryList(Page page, Long id) {
		//获取博客列表
		Page<BContent> pageData = this.page(page, new QueryWrapper<BContent>()
				.eq("status", 2)
				.eq("is_delete", 0)
				.eq(id != null, "type_id", id)
				.eq("status", 2)
				.orderByDesc("create_time")
		);

		// 获取文章的分类和标签
		for (BContent bContent : pageData.getRecords()) {
			// 获取分类名称
			BType bType = bTypeService.getById(bContent.getTypeId());
			bContent.setTypeName(bType.getName());
			// 获取标签名称
			List<String> tags = Arrays.asList(bContent.getTagsId().split(","));
			List<Long> longL = tags.stream().map(tag -> Long.valueOf(tag)).collect(Collectors.toList());
			List<BTag> bTags = bTagService.list(new QueryWrapper<BTag>().in("id", longL));

			bContent.setTags(bTags);

			// 查询作者
			BUser bUser = bUserService.getById(bContent.getUserId());
			bContent.setAuthor(bUser.getNickname());

		}

		return pageData;
	}

	// 获取博客列表
	@Override
	public Page<BContent> PageList(Page page, Long id) {
		Page<BContent> pageList = this.page(page, new QueryWrapper<BContent>()
				.eq(id != null, "id", id)
				.and(i -> i.eq("status", 2).or().eq("status", 3))
				.orderByDesc("create_time")
		);
		if (pageList.getRecords().size() <= 0) {
			return null;
		}

		for (BContent bContent : pageList.getRecords()) {
			BUser bUser = bUserService.getById(bContent.getUserId());
			if (bUser != null) {
				bContent.setAuthor(bUser.getNickname());
			}
			BType bType = bTypeService.getById(bContent.getTypeId());
			if (bType != null) {
				bContent.setTypeName(bType.getName());
			}
		}
		return pageList;
	}


	@Override
	public List<BContent> selectByStatus(Integer status) {
		List<BContent> bContentList = new ArrayList<>();
		if (status == 0) {
			// 查全部(1,3)
			bContentList = bContentMapper.selectByTwoStatus(1, 3);
		} else if (status == 1) {
			bContentList = bContentMapper.selectByStatus(1);
		} else if (status == 2) {
			bContentList = bContentMapper.selectByStatus(3);
		}

		if (bContentList.size() <= 0) {
			return null;
		}

		for (BContent bContent : bContentList) {
			// 查分类名称
			BType bType = bTypeService.getById(bContent.getTypeId());
			BUser bUser = bUserService.getById(bContent.getUserId());

			bContent.setTypeName(bType.getName());
			bContent.setAuthor(bUser.getNickname());
		}

		System.out.println("---------------" + bContentList);
		return bContentList;
	}

	@Override
	public Object searchPage(Page<BContent> objectPage, AdminSearchVo adminSearchVo) {
		System.out.println(adminSearchVo);

		System.out.println(adminSearchVo.getTitle().isEmpty() + "---" + (adminSearchVo.getTitle() != null) + "--" + (adminSearchVo.getTitle() == ""));

		boolean isTitle = adminSearchVo.getTitle().isEmpty();

		Page<BContent> page = this.page(objectPage, new QueryWrapper<BContent>()
				.like(!isTitle, "title", adminSearchVo.getTitle())
				.and(adminSearchVo.getType() != null, i -> i.eq("type_id", adminSearchVo.getType()))
				.and(adminSearchVo.getModel() != null, i -> i.eq("model", adminSearchVo.getModel()))
				.and(adminSearchVo.getDate() != null, i -> i.gt("create_time", adminSearchVo.getDate()))
				.and(i -> i.eq("status", 2).or().eq("status", 3))
		);

		for (BContent bContent : page.getRecords()) {
			BUser bUser = bUserService.getById(bContent.getUserId());
			bContent.setAuthor(bUser.getNickname());
			BType bType = bTypeService.getById(bContent.getTypeId());
			bContent.setTypeName(bType.getName());
		}

		System.out.println(page.getRecords().size() + "--->" + page.getRecords());
		return page;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean insertBlog(ClientAddContent content, String token) {
		if (content.getId() != null) {
			// 修改已经存在的文章
			System.out.println("执行这里" + content.getId());
			BContent bContent = this.getById(content.getId());
			BContent newContent = updateContent(bContent, content);
			return this.updateById(newContent);
		}

		Date date = new Date();
		BContent bContent = new BContent();
		BUser bUser = bUserService.getCurrentId(token);

		bContent.setContent(content.getContent());
		bContent.setTagsId(content.getTag());
		bContent.setUserId(bUser.getId());
		bContent.setCreateTime(LocalDateTime.now());
		bContent.setTypeId(content.getType());
		bContent.setTitle("# " + content.getTitle());
		bContent.setDescription(content.getDescription());
		bContent.setFirstPicture(content.getFirstPicture());
		bContent.setLike(0L);
		bContent.setCollect(0L);
		bContent.setStatus(content.getStatus());
		bContent.setIsDelete(0);
		bContent.setUpdateTime(LocalDateTime.now());
		bContent.setHistoryPeopleCount(0L);
		bContent.setModel(content.getModel());
		bContent.setIsReview(content.getReview());
		bContent.setContentId(IdUtil.fastSimpleUUID());

		//将数据存储到数据库
		boolean save = this.save(bContent);
		if (content.getStatus() == 4) {
			// 延时发布
			// 将用户id、文章id存储到缓存
			// 存储的内容
			String msgValue = bUser.getId() + "-" + bContent.getContentId();
			// 向延时队列发送消息，并设置TTL
			// 获取延时时间
			long between = DateUtil.between(date, content.getDelayTime(), DateUnit.SECOND);
//			sender.sendDelayMsg(String.valueOf(msgValue), (int) between * 1000);
			// 最后在消息转为死信之后从缓存获取文章id将文章发布，status修改为 1
		}

		BContent contentId = this.getOne(new QueryWrapper<BContent>()
				.eq("content_id", bContent.getContentId())
		);
		for (ImageList imageList : content.getImageList()) {
			BContentImage bContentImage = new BContentImage();
			bContentImage.setContentId(contentId.getId());
			bContentImage.setFlag(imageList.getFlag());
			bContentImage.setImgUrl(imageList.getPath());
			bContentImageService.save(bContentImage);
		}

		return save;
	}

	private BContent updateContent(BContent bContent, ClientAddContent content) {

		if (content.getTag() != null || content.getTag() != "") {
			bContent.setTagsId(content.getTag());
		}
		if (content.getFirstPicture() != null || content.getFirstPicture() != "") {
			bContent.setFirstPicture(content.getFirstPicture());
		}
		bContent.setModel(content.getModel());
		bContent.setStatus(content.getStatus());
		bContent.setUpdateTime(LocalDateTime.now());
		bContent.setContent(content.getContent());
		bContent.setTypeId(content.getType());
		bContent.setDescription(content.getDescription());
		bContent.setTitle("# " + content.getTitle());
		bContent.setIsReview(content.getReview());
		return bContent;
	}

	@Override
	public Object getPublished(HttpServletRequest request, Integer status) {
		// 已发布
		Integer stu = 2;
		if (status == 2) {
			// 延时发布
			stu = 4;
		} else if (status == 3) {
			// 草稿箱
			stu = 1;
		}
		String token = request.getHeader("token");
		Claims claim = jwtUtil.getClaimByToken(token, Const.GRADE_USER);
		String subject = claim.getSubject();

		List<BContent> list = this.list(new QueryWrapper<BContent>()
				.eq("status", stu)
				.eq("is_delete", 0)
				.eq("user_id", Integer.valueOf(subject))
		);

		return list;
	}

	@Override
	public Object getCollect(HttpServletRequest request) {
		Claims claim = jwtUtil.getClaimByToken(request.getHeader("token"), Const.GRADE_USER);
		String subject = claim.getSubject();

		List<BCollect> contentIds = bCollectMapper.selectList(new QueryWrapper<BCollect>()
				.eq("user_id", Integer.valueOf(subject))
		);
		List<Integer> collect = contentIds.stream().map(BCollect::getContentId).collect(Collectors.toList());
		List<BContent> bContents = new ArrayList<>();
		if (collect.size() > 0) {
			bContents = this.list(new QueryWrapper<BContent>().in("id", collect));
		}
		return bContents;
	}

	@Override
	public Object getLike(HttpServletRequest request) {
		Claims claim = jwtUtil.getClaimByToken(request.getHeader("token"), Const.GRADE_USER);
		String subject = claim.getSubject();
		List<BUserLike> bUserLikes = bUserLikeMapper.selectList(new QueryWrapper<BUserLike>().eq("user_id", Integer.valueOf(subject)));
		List<Integer> contentIds = new ArrayList<>();
		List<BContent> bContents = new ArrayList<>();
		if (bUserLikes.size() > 0) {
			contentIds = bUserLikes.stream().map(BUserLike::getContentId).collect(Collectors.toList());
			bContents = this.list(new QueryWrapper<BContent>().in("id", contentIds));
		}
		return bContents;
	}

	@Override
	public Object selectSearch(ContentSearchVo searchVo, HttpServletRequest request) {
		String token = request.getHeader("token");
		Claims claim = jwtUtil.getClaimByToken(token, Const.GRADE_USER);
		List<BContent> list = this.list(new QueryWrapper<BContent>()
				.eq("user_id", Integer.valueOf(claim.getSubject()))
				.eq(searchVo.getModel() != null, "model", searchVo.getModel())
				.eq(searchVo.getType() != null, "type_id", searchVo.getType())
				.ge(searchVo.getYear() != null, "create_time", searchVo.getYear())
				.like(searchVo.getKeyword() != null, "title", searchVo.getKeyword())
				.eq("status", 2)
				.eq("is_delete", 0)
				.orderByDesc("create_time")
		);
		return list;
	}

	@Override
	public Object pigeonhole() {
		List<PigeonholePo> list = bContentMapper.selectByPigeonhole();
		for (PigeonholePo pigeonholePo : list) {
			BUser bUser = bUserService.getById(pigeonholePo.getUserId());
			pigeonholePo.setBUser(bUser);
			BContent bContent = bContentMapper.selectById(pigeonholePo.getId());
			pigeonholePo.setBContent(bContent);
		}
		Map<String, List<PigeonholePo>> collect = list.stream().collect(Collectors.groupingBy(PigeonholePo::getYear));

		List<PigeonholeDto> dtoList = new ArrayList<>();
		for (Map.Entry<String, List<PigeonholePo>> entry : collect.entrySet()) {
			PigeonholeDto pigeonholeDto = new PigeonholeDto();
			pigeonholeDto.setYear(entry.getKey());
			pigeonholeDto.setList(entry.getValue());
			dtoList.add(pigeonholeDto);
		}

		return dtoList;
	}

	/**
	 * 统计处理
	 *
	 * @return
	 */
	//
	@Override
	public Object statistics() throws JsonProcessingException {
		List<YearPo> list = new ArrayList<>();
		ObjectMapper objectMapper = new ObjectMapper();
		list = bContentMapper.getYearByCount();
		System.out.println(list);
		String yearStatistics = redisUtil.get("year_statistics");
		if (yearStatistics == null || yearStatistics.isEmpty()) {
			list = bContentMapper.getYearByCount();
			// 获取每一年的发布量
			String json = objectMapper.writeValueAsString(list);
			redisUtil.set("year_statistics", json);
			System.out.println("执行------" + list);
		}
		List<YearPo> poList = objectMapper.readValue(yearStatistics, new TypeReference<List<YearPo>>() {
		});

		return poList;
	}

	@Override
	public Object getMonthByYear(String year) throws JsonProcessingException {

		List<MonthPo> monthByYear = bContentMapper.getMonthByYear(year);
		return monthByYear;
	}

}




